import type { Component, PropType } from 'vue';

export interface EventArg {
  formModel: Record<string, any>;
  formDiabled: boolean;
  formFiledItem: FormFiled;
  formFiledList?: FormFiled[]; // 与 formFiledListLocal 无区别
  formFiledListLocal?: FormFiled[];
  componentVal?: any;
  updateFiled: (x: FormFiled | FormFiled[]) => void;
  resetFiled: (x: string | string[]) => void;
}

export type Event = (x: EventArg) => unknown;

export type Events = Record<string, Event>;

export interface PropsCol {
  span?: number;
  offset?: number;
  order?: number;
  xs?: number | { [key: string]: any };
  sm?: number | { [key: string]: any };
  md?: number | { [key: string]: any };
  lg?: number | { [key: string]: any };
  xl?: number | { [key: string]: any };
  xxl?: number | { [key: string]: any };
  flex?: number | string | 'initial' | 'auto' | 'none';
}

interface OnFieldValueChangeItem {
  // formModel 的 某个字段
  keys: string | string[];
  // 执行函数
  handle: (x: EventArg & { newVal: any; oldVal: any }) => void;
  options?: {
    // 是否立即执行，同vue watch
    immediate?: boolean;
    // 深度监听，同vue watch
    deep?: boolean;
  };
}

export interface FormFiled {
  filed: string | string[];
  label?: string;
  labelWidth?: string;
  component?: string | Component;
  events?: Events;
  ifShow?: (x: EventArg) => boolean;
  // 监测表单某项值变化
  onFieldValueChange?: OnFieldValueChangeItem[];
  slots?: {
    label?: string | ((x: EventArg) => any);
    component?: string | ((x: EventArg) => any);
    formItem?: string | ((x: EventArg) => any);
    inComponentSlots?: Record<string, string | ((x: EventArg) => any)>;
    help?: string | ((x: EventArg) => any);
    extra?: string | ((x: EventArg) => any);
  };
  props?: {
    formItem?: Record<string, any> | ((x: EventArg) => Record<string, any>);
    col?: PropsCol | ((x: EventArg) => PropsCol);
    component?: Record<string, any> | ((x: EventArg) => Record<string, any>);
  };
  rowClass?: string;
}

export const formProps = {
  modelValue: {
    type: Object as PropType<Record<string, any>>,
    default: () => {
      return {};
    },
  },
  formFiledList: {
    type: Object as PropType<FormFiled[]>,
    default: () => {
      return [];
    },
  },
  labelWidth: {
    type: String as PropType<string>,
    default: '60px',
  },
  /**
   * 是否显示label
   */
  hideLabel: {
    type: Boolean as PropType<boolean>,
    default: false,
  },
  disabled: {
    type: Boolean as PropType<boolean>,
    default: false,
  },
  rootRow: {
    type: Object as PropType<Record<string, any>>,
    default: () => {
      return {};
    },
  },
  showColon: {
    type: Boolean as PropType<boolean>,
  },
  size: {
    type: String as PropType<string>,
    default: 'medium',
  },
  formItemStyles: {
    type: Object as PropType<Record<string, any>>,
    default: () => {
      return {};
    },
  },
  labelAlign: {
    type: String as PropType<string>,
    default: 'right',
  },
};

export interface MergeConfigItem extends FormFiled {
  detail?: Partial<FormFiled>;
  edit?: Partial<FormFiled>;
}

export type MergeConfigType = 'detail' | 'edit';
